#ifndef CMD_HANDLER_H
#define CMD_HANDLER_H

#include <map>
#include <string>

#include "util.h"

typedef std::map<std::string, std::string> Arg;
typedef std::string (*handle_t)(Arg &arg_, void* gm_) ;


struct cmd_handler_t {
    virtual ~cmd_handler_t(){}

    struct cmd_t {
        std::string opts;
        handle_t handle;
        cmd_t(const std::string &opts_, handle_t handle_):opts(opts_), handle(handle_){}
        cmd_t(){handle=NULL;}

    };


    bool init()
    {
        bool rtv = _register_cmds();

        return rtv;
    }

    void destroy()
    {
        _handlers.clear();
    }

    virtual std::string proc_gmcmd(const char* cmd_, void* gm_);

    virtual bool _register_cmds() { return true; }

    cmd_handler_t(const char* name_ = "noname"):_name(name_){}
    bool _register_cmd(const char* cmd_, const char* args_, handle_t handler_)
    {
        if(_handlers.count(cmd_)>0) {
            UTIL_LOG(E, "cmd_handler_t::_register_cmd %s already exist", cmd_);
            return false;
        }
        _handlers.insert(std::make_pair(cmd_, cmd_t(args_, handler_)));

        return true;
    }

    std::map<std::string, cmd_t> _handlers;
    const char* _name;
};

inline double get_float_arg(Arg &arg_, const char* name_, double def_)
{
    if(arg_.count(name_) >= 1)
        return atof(arg_[name_].c_str());
    else
        return def_;
}

inline const char* get_str_arg(Arg &arg_, const char* name_, const char* def_)
{
    if(arg_.count(name_) >= 1)
        return arg_[name_].c_str();
    else
        return def_;
}

inline int get_int_arg(Arg &arg_, const char* name_, int def_)
{
    if(arg_.count(name_) >= 1)
        return atoi(arg_[name_].c_str());
    else
        return def_;
}

inline int64_t get_int64_arg(Arg &arg_, const char* name_, int64_t def_)
{
    if(arg_.count(name_) >= 1)
        return atoll(arg_[name_].c_str());
    else
        return def_;
}

#endif
